<template>
	<scroll
		ref="listview"
		class="listview"
		:listen-scroll="listenScroll"
		:probe-type="probeType"
		:data="data"
		@scroll="scroll"
	>
		<ul>
			<li ref="listGroup" v-for="group in data" :key="group.title" class="list-group">
				<h2 class="list-group-title">{{group.title}}</h2>
				<ul>
					<li
						v-for="item in group.list"
						:key="item.id"
						class="list-group-item"
						@click="selectItem(item)"
					>
						<img class="avatar" v-lazy="item.pic" alt="avatar" />
						<span class="name">{{item.name}}</span>
					</li>
				</ul>
			</li>
		</ul>
		<div
			class="list-shortcut"
			@touchstart.stop.prevent="onShortcutTouchStart"
			@touchmove.stop.prevent="onShortcutTouchMove"
			@touchend.stop.prevent
		>
			<ul>
				<li
					v-for="(item, index) in shortcutList"
					:key="item"
					:data-index="index"
					class="item"
					:class="{'current': currentIndex === index}"
				>{{item}}
				</li>
			</ul>
		</div>
		<div ref="fixed" class="list-fixed" v-show="fixedTitle">
			<h1 class="fixed-title">{{fixedTitle}}</h1>
		</div>
		<div class="loading-container" v-show="!data.length">
			<loading></loading>
		</div>
	</scroll>
</template>

<script>
	import Scroll from '@/base/scroll/scroll';
	import Loading from '@/base/loading/loading';
	import { prefixStyle, getData } from '@/common/js/dom';

	const TITLE_HEIGHT = 30;
	const ANCHOR_HEIGHT = 18;
	const transform = prefixStyle('transform');

	export default {
		props: {
			data: {
				type: Array,
				default: () => []
			}
		},
		data() {
			return {
				scrollY: -1,
				currentIndex: 0,
				diff: -1
			}
		},
		created() {
			this.probeType = 3;
			this.listenScroll = true;
			this.touch = {};
			this.listHeight = [];
		},
		computed: {
			shortcutList() {
				return this.data.map(item => item.title);
			},
			fixedTitle() {
				if (this.scrollY > 0) return '';
				return this.data[this.currentIndex] ? this.data[this.currentIndex].title : '';
			}
		},
		methods: {
			selectItem(item) {
				this.$emit('select', item);
			},
			refresh() {
				this.$refs.listview.refresh();
			},
			scroll(pos) {
				this.scrollY = pos.y;
			},
			onShortcutTouchStart(e) {
				let anchorIndex = getData(e.target, 'index');
				let firstTouch = e.touches[0];
				this.touch.y1 = firstTouch.pageY;
				this.touch.anchorIndex = anchorIndex;
				this._scrollTo(anchorIndex);
			},
			onShortcutTouchMove(e) {
				let firstTouch = e.touches[0];
				this.touch.y2 = firstTouch.pageY;
				let delta = (this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT | 0;
				let anchorIndex = parseInt(this.touch.anchorIndex) + delta;
				this._scrollTo(anchorIndex);
			},
			_scrollTo(index) {
				if (isNaN(index)) return;
				if (index < 0) {
					index = 0;
				}
				if (index > this.listHeight.length - 2) {
					index = this.listHeight.length - 2;
				}
				this.scrollY = -this.listHeight[index];
				this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 0);
			},
			_calculateHeight() {
				this.listHeight = [];
				const list = this.$refs.listGroup;
				let height = 0;
				this.listHeight.push(height);
				for (let i = 0; i < list.length; i++) {
					let item = list[i];
					height += item.clientHeight;
					this.listHeight.push(height);
				}
			}
		},
		watch: {
			data() {
				setTimeout(() => {
					this._calculateHeight();
				}, 20);
			},
			scrollY(newY) {
				const listHeight = this.listHeight;
				// 当滚动到顶部时，newY > 0
				if (newY > 0) {
					this.currentIndex = 0;
					return;
				}
				// 当滚动到中部时
				for (let i = 0; i < listHeight.length - 1; i++) {
					let height1 = listHeight[i];
					let height2 = listHeight[i + 1];
					if (-newY >= height1 && -newY < height2) {
						this.currentIndex = i;
						this.diff = height2 + newY;
						return;
					}
				}
				// 当滚动到底部且-newY > 最后一个元素的上限时
				this.currentIndex = listHeight.length - 2;
			},
			diff(newVal) {
				let fixedTop = (newVal > 0 && newVal < TITLE_HEIGHT) ? newVal - TITLE_HEIGHT : 0;
				if (this.fixedTop === fixedTop) return;
				this.fixedTop === fixedTop
				this.$refs.fixed.style[transform] = `translate3d(0, ${fixedTop}px, 0)`;
			}
		},
		components: {
			Scroll,
			Loading
		}
	}

</script>

<style lang="stylus" scoped>
	@import "../../common/stylus/variable"

	.listview
		position: relative
		width: 100%
		height: 100%
		overflow: hidden
		background: $color-background
		.list-group
			padding-bottom: 10px
			.list-group-title
				height: 30px
				line-height: 30px
				padding-left: 20px
				font-size: $font-size-small
				color: $color-text-l
				background: $color-highlight-background
			.list-group-item
				display: flex
				align-items: center
				padding: 20px 0 0 30px
				.avatar
					width: 50px
					height: 50px
					border-radius: 50%
				.name
					margin-left: 20px
					color: $color-text-l
					font-size: $font-size-medium
		.list-shortcut
			position: absolute
			z-index: 30
			right: 0
			top: 50%
			transform: translateY(-50%)
			width: 20px
			padding: 20px 0
			border-radius: 10px
			text-align: center
			background: $color-background-d
			font-family: Helvetica
			.item
				padding: 3px
				line-height: 1
				color: $color-text-l
				font-size: $font-size-small
				&.current
					color: $color-theme
		.list-fixed
			position: absolute
			top: 0
			left: 0
			width: 100%
			.fixed-title
				height: 30px
				line-height: 30px
				padding-left: 20px
				font-size: $font-size-small
				color: $color-text-l
				background: $color-highlight-background
		.loading-container
			position: absolute
			width: 100%
			top: 50%
			transform: translateY(-50%)
</style>
